/**
 * Copyright (c) 2022 Presto Labs Pte. Ltd.
 * Author: Ju
 */

#pragma once

#include <boost/asio/io_service.hpp>

#include "coin2/base/cpp_feature.h"
#include "coin2/base/scheduler.h"

namespace coin2::exchange::base::order {

struct CpuTimeData {
  CpuTimeData() : user_time(0), sys_time(0), prev_ts(0) {}

  long user_time;
  long sys_time;
  long prev_ts;
};

struct SelfMemInfo {
  uint64_t
      size;  // total program size, same as (VmSize)/4 in /proc/[pid]/status
  uint64_t resident;  // same as (VmRSS)/4 in /proc/[pid]/status
  uint64_t share;     // shared pages
  uint64_t text;      // text (code)
  uint64_t lib;       // library
  uint64_t data;      // data + stack
  uint64_t dt;        // dirty pages
};                    // in pages

bool GetSelfMemInfo(SelfMemInfo *info);

class SystemInfo : public coin2::base::NonCopyOrMovable {
 public:
  // five Seconds
  explicit SystemInfo(boost::asio::io_context *ioc,
                      std::shared_ptr<Scheduler> timer,
                      uint32_t interval_s = 5);

  ~SystemInfo();
  double GetCpuUsage() const;

 private:
  void OnTimer();

  double GetSelfCpuUsage(CpuTimeData *prev);

 private:
  boost::asio::io_context *ioc_;
  std::shared_ptr<Scheduler> timer_;

  double cpu_usage_;
  CpuTimeData cpu_time_data_;
};

inline double SystemInfo::GetCpuUsage() const { return cpu_usage_; }
}  // namespace coin2::exchange::base::order